#include <stdio.h>
#include <stdlib.h>
#include "scanner.h"
#include "parser.h"

Input* jscan_init() {
  Input *inp;
  MEM_NEW(inp, sizeof(Input) + (sizeof(CHAR) * (BUFFER_SIZE + 2)));

  inp->buffer = (CHAR*) (&inp->buffer) + sizeof(CHAR*);
  inp->limit = inp->buffer_end = inp->buffer + BUFFER_SIZE;
  inp->start = inp->cursor = inp->marker = inp->buffer;
  inp->line = 1;
  
  return inp;
}

void jscan_fill(Input* inp) {
  if(feof(inp->finput))
	return;
  
  size_t to_shift = inp->limit - inp->start,
	to_fill = inp->start - inp->buffer,
	filled = 0;
  CHAR *dest = NULL;

  if(to_fill == 0) {
	/* Cursor unmoved, fill the whole buffer */
	filled = fread(inp->buffer, sizeof(CHAR), BUFFER_SIZE, inp->finput);
	if(filled < BUFFER_SIZE)
	  inp->limit += filled;
  }
  else {
	/* Cursor moved, shift unconsumed buffer, fill the rest */
	memmove(inp->buffer, inp->start, to_shift);
	inp->start -= to_fill;
	inp->cursor -= to_fill;
	inp->marker -= to_fill;
	inp->limit -= to_fill;
	filled = fread(inp->limit, sizeof(CHAR), to_fill, inp->finput);
	if(to_shift + filled < BUFFER_SIZE)
	  inp->limit += filled;
  }
}

void jscan_open(Input* inp, const char* fn) {
  inp->finput = fopen(fn, "rb");
  if(inp->finput == NULL) {
  }
  else {
	jscan_fill(inp);
  }
}

void jscan_free(Input* inp) {
  fclose(inp->finput);
  MEM_FREE(inp);
}


static UINT proc_identifier(Input *inp) {
  Keyword *kw = jscan_is_keyword(inp->start, inp->cursor - inp->start);
  if(kw == NULL)
	return T_IDENTIFIER;
  else {
	return kw->token;
  }
}



#define YYCTYPE CHAR
#define YYLIMIT inp->limit
#define YYMARKER inp->marker
#define YYCURSOR cursor
#define YYFILL(N) jscan_fill(inp)
#define RET(V) { inp->cursor = cursor; return V; }
UINT jscan_scan(Input *inp) {
  /*!re2c
	eol = "\n";
	eof = "\000";
	digit = [0-9];
	integer = digit+;
	alpha = [A-Za-z_];
	any = [\000-\0377];
	space = [ \h\t\v\f\r];
  */
  CHAR *cursor = inp->cursor;

 standard:
  inp->start = cursor;
  /*!re2c
	space+ { goto standard; }
	"\n" { inp->line += 1; goto standard; }
	"\/*" { goto comment; }

	alpha (alpha|digit)* { RET(proc_identifier(inp)); }

	"{" { RET(T_LPAREN); }
	"}" { RET(T_RPAREN); }

	eof { RET(T_EOF); }
	any { RET(T_EOF); }
   */

 comment:
  /*!re2c
	"*\/" { goto standard; }
	"\n" { inp->line += 1; goto comment; }
	any+ { goto comment; }
   */

  return T_EOF;
}

/* -
 * Local Variables:
 * mode: c
 * End:
 * - */
